package poker_sim;

import java.util.Stack;

public class Table {

    int Round = 0;
    int gamestate = 0;
    UI Interface;
    Player[] thePlayers = new Player[9];
    public Deck _Deck = new Deck();
    public CardCollection TableCards;
    public PokerLogic pokerLogic;
    public InterfaceClass UIC;//user interface class
    Blind blind = new Blind(100, 50, 10);

    public Table(UI _Interface) {
        Interface = _Interface; 
        PlayerSitting();
        UIC = new InterfaceClass(this, Interface);
        
        pokerLogic = new PokerLogic(this, UIC);
        TableCards = new CardCollection(5, Interface.vTableCards);
        NextHand();

    }

    public void PlayerSitting() {
        for (int i = 0; i < 9; i++) {
            //setname
            thePlayers[i] = new Player("Player" + i, Interface);
            //TODO dont put the setscore in the new hand, this means the next hand stats are reset
            thePlayers[i].Setscore(1000);
        }
        thePlayers[0].Setname("Mitchibal");
    }

    public void NextHand() {
        TableCards.Reset();
        UIC.ResetHandCards();
        
        DeckFactory DF = new DeckFactory(_Deck);
        Round++;
        gamestate = 0;
        //Create buffer for ranking text
        String HandRankingText = "";

        //Initialize players
        for (int i = 0; i < 9; i++) {
            //draw the hand from the deck
            thePlayers[i].SetHand(_Deck.drawCard(), _Deck.drawCard());
            UIC.UpdateHandCards(0);
            UIC.UpdateHandCards(1);
            //Calculate possibilities
            pokerLogic.FirstCalculation(i);
            //debug purpose
            //System.out.println("Handvalue: " + pokerLogic.HandValue(i));
        }
        //Set blinds
        
        AssignBlinds();

    }

    public void game() {
        gamestate++;
        switch (gamestate) {
            case 1:
                Flop();

                break;

            case 2:
                Turn();
                break;

            case 3:
                River();
                break;

            default:
            //throw new AssertionError();
        }

    }

    public void Flop() {
        //increament the stage of this hand
        pokerLogic.Nextstage();
        //Burn a card, don't catch the value
        _Deck.drawCard();
        //Put 3 cards on the table var
        TableCards.AddCard(_Deck.drawCard());
        TableCards.AddCard(_Deck.drawCard());
        TableCards.AddCard(_Deck.drawCard());
        //Show the cards on the table
        for (int i = 0; i < 3; i++) {
            UIC.UpdateTableCards(TableCards.card[i], i);
        }
        //Load the cards into the logic engine
        
        pokerLogic.onFlop();
    }

    public void Turn() {
        //increament the stage of this hand
        pokerLogic.Nextstage();
        //Burn a card
        _Deck.drawCard();
        //Put 1 card on the table var
        TableCards.AddCard(_Deck.drawCard());
        //Load the new card on the table
        UIC.UpdateTableCards(TableCards.card[3], 3);
        //Load the new card into the logic engine
        pokerLogic.onTurn();
    }

    public void River() {
        //increament the stage of this hand
        pokerLogic.Nextstage();
        //Burn a card
        _Deck.drawCard();
        //Put 1 card on the table var
        TableCards.AddCard(_Deck.drawCard());
        //Load the new card on the table
        UIC.UpdateTableCards(TableCards.card[4], 4);
        //Load the new card into the logic engine
        pokerLogic.onRiver();
    }

    public void UpdateStats() {
        UIC.UpdateStatistics(thePlayers);
    }

    public void AssignBlinds() {
        for (int i = 0; i < 9; i++) {
            thePlayers[i].AddScore(-blind.GetAnte());
            UIC.UpdateBlinds(0, i);
        }
        int MaxPlayers = thePlayers.length;
        int BigBlindLocation = Round % MaxPlayers;
        int SmallBlindLocation = (Round - 1) % MaxPlayers;
        UIC.UpdateBlinds(blind.GetBigBlind(), BigBlindLocation);
        UIC.UpdateBlinds(blind.GetSmallBlind(), SmallBlindLocation);
        Player BigBlindPlayer = thePlayers[BigBlindLocation];
        Player SmallBlindPlayer = thePlayers[SmallBlindLocation];
        BigBlindPlayer.AddScore(-blind.GetBigBlind());
        SmallBlindPlayer.AddScore(-blind.GetSmallBlind());
    }
}
